<?php
class SocketServer {
    public $ip     = '127.0.0.1';
    public $port   = '6666';
    public $sock   = null;
    public $clientAll    = array();
    public $clientTag    = array();
    public $client = false;

    public function create(){
        $this->sock     = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
        if($this->sock < 0)
            die('socket_create is failed!'.socket_strerror(socket_last_error()));

        socket_bind($this->sock, $this->ip, $this->port);
        socket_listen($this->sock, 10);

        echo "socket create success! listen ".$this->ip.":".$this->port."...\n";

        while(true)
            $this->listen();
    }

    private function listen(){
        $this->client     = socket_accept($this->sock);
        if($this->client){
            $send   = "The connect is create!\n";
            socket_write($this->client, $send, strlen($send));

            //客户端指令发送
            $directive    = json_decode(socket_read($this->client, 2048), true);
            if(is_array($directive))
                $this->execute($directive);
        }
    }

    /**
     * 客户端注册
     */
    public function signup($directive){
        if($directive['client_id']);
            $this->clientAll[$directive['client_id']]  = $this->client;
        if($directive['client_tag'])
            $this->clientTag[$directive['client_tag']][]    = $this->client;

        $this->sendInfo('signup is success!', $this->client);

    }

    /**
     * 命令解析
     * @param  array $directive 指令
     * @return null          
     */
    private function execute($directive){
        echo "execute directive:".json_encode($directive)."...\n";
        switch($directive['function']){
            case 'broadcast':
                $this->broadcast($directive);
            break;

            case 'signup':
                $this->signup($directive);
            break;

            case 'send_info_by_id':
                $this->sendInfoById($directive);
            break;
        }
    }

    /**
     * 发送广播
     * @param  array $directive 指令参数    
     * @return null
     */
    private function broadcast($directive){
        $message    = $directive['message'];
        foreach($this->clientAll as $client){
            socket_write($client, $message, strlen($message));
        }
    }

    /**
     * 根据Id发送消息
     * @param  array $directive 指令信息
     * @return null            
     */
    private function sendInfoById($directive){
        $cliendId   = $directive['client_id'];
        $message    = $directive['message'];

        $tarClient  = $this->clientAll[$cliendId];
        if(!$tarClient){
            $this->sendInfo('It is not valid client_id!', $this->client, 0);
        }else{
            $this->sendInfo($message, $tarClient);
            $this->sendInfo('Send success!', $this->client);
        }
    }

    /**
     * 发送消息
     * @param  minxed  $info   发送的信息
     * @param  object  $client 客户端句柄
     * @param  integer $code   状态码
     * @return null          
     */
    public function sendInfo($info, $client, $code = 1){
        $info   = array(
            'info' => $info,
            'code' => $code
        );
        $info   = json_encode($info);
        socket_write($client, $info, strlen($info));
    }
}

$socket     = new SocketServer();
$socket->create();